#include "fonction_base.hpp"

void text_entry(string & file)
{
  char c(' ');
  file="";

  // Boucle de saisi des caracteres
  while(c!='\n')
    {
      // Saisi du caractere
      c=getchar();

      // Check du caractere de fin et ajout a file
      if(c!='\n')
	file+=c;
      else
	file+='\0';
    }
}

void test_open_file(string & name_file,int i)
{
  char * c;
  FILE * file_test;

  string phrase("Donner un fichier pour ");
  if(i == 0)
    phrase+="l'index : ";
  else
    phrase +="remplir l'index : ";

  // Redemande un fichier pour lindex
  do{
    cout << phrase;

    // Entre le nom du fichier
    text_entry(name_file);
    c=&name_file[0];

    // Verifie si le fichier existe
    file_test=fopen(c,"r");
  }while(file_test == NULL);

  // Ferme le fichier
  fclose(file_test);
}

void separet_word(string line,int cpt,chained_word & c_w)
{
  string word("");
  int i=0;

  // Boucle de lecture  
  while(line[i]!='\n' && line[i]!=EOF)
    {
      // Si le caractere nest pas un espace ou une tabulation ou une fin de ligne alors on rajoute le caractere a word
      // Sinon on rajoute a la liste chaine ou pas
      if(line[i]!=' ' && line[i]!='\0' && line[i]!='\t' && line[i]!='\n')
	word+=line[i];
      else
	{
	  // Si word est non vide alors on rajoute a la fin du mot \0 et on le rajoute a la liste chainee
	  if(word!="")
	    {
	      word+='\0';
	      add_word(c_w,word,cpt);
	    }
	  word="";
	}
      ++i;
    }

  // Si le mot non vide ou non \n alors on rajoute le mot a la fin du mot \0 et on le rajoute a la liste chaine
  if(word != "" && word != "\n" && line[i]!=EOF)
    {
      word+='\0';
      add_word(c_w,word,cpt);
    }
}

void get_line(FILE * file,string & line,int & cpt)
{
  char cara;
  line="";

  do
    {
      // cara recoit un caractere
      // file passe au caractere suivant
      cara=fgetc(file);

      if(cara!=EOF)
	line+=cara;
    }while(cara!='\n' && cara !=EOF);

  // Si la ligne est vide alors on est a la fin du fichier
  if(line=="")
    line=EOF;
  else
    line+='\n';
  ++cpt;
}

void transforme(string & line,int position)
{
  // Si le caractere est au debut ou a la fin alors on le remplace par un espace
  // Sinon on check le mot 
  if(position-1 >= 0 && (line[position+1] != '\n' || line[position+1] != EOF || line[position+1] != ' ' || line[position+1] != '\t'))
    {
      // Si le mot compose au debut du - ou du ' a une lettre minuscule et le mot compose a la fin du - ou du ' a une lettre majuscule ou minuscule alors on fait rien
      // Sinon on met un espace
      if(!((('A' <= line[position+1] && line[position+1] <= 'Z') || ('a' <= line[position+1] && line[position+1] <= 'z'))&&('a' <= line[position-1] && line[position-1] <= 'z')))
	line[position] = ' ';
    }
  else
    line[position] = ' ';
}

void read_file(string & name_file,chained_word & c_w)
{
  // p_file pointe sur le 1er caractere de name_file
  // Obligatoire si on veux ouvrir un fichier
  char * p_file=&name_file[0];
  FILE * file;
  string line;
  int cpt=0;

  // Ouverture du fichier
  file=fopen(p_file,"r");

  // Si file = NULL alors le fichier nexiste pas
  if(file != NULL)
    {
      cout << "Ouverture du fichier en lecture" << endl;

      // Positionnnement de file au debut de fichier
      fseek(file,0,SEEK_SET);

      // Boucle de lecture
      do
	{
    	  // Met ds line une ligne du fichier file
    	  get_line(file,line,cpt);
	  cout << cpt << " " << line;

	  modif_cara(line);

	  cout << cpt << " " << line;

    	  // Separe chaque mot de line et met ds c_w
    	  separet_word(line,cpt,c_w);
    	}while(line[0] != EOF);

      // Fermeture du fichier
      fclose(file);
      cout << endl << "Fermeture du fichier en lecture" << endl;
    }
  else
    cout << "Le fichier n'a pas voulu s'ouvrir" << endl;
}

void initialisation_index(chained_index & c_i)
{
  //  FILE * file;
  string name_file,mot="";
  chained_word c_w=NULL;

  // Initialisation de c_i donner en parametre de la fonction
  created_chained_index(c_i);

  // Demande le nom du fichier
  test_open_file(name_file,0);

  // Stockage dans la liste chainee
  read_file(name_file,c_w);

  while(c_w != NULL)
    {
      // Le mot de tete est supprimer de c_w et est stocke ds mot
      mot=delete_word(c_w);
      // Ajout de mot dans c_i (chained_index)
      add_word_index(c_i,mot);
    }
}

void get_word(chained_word c_file,chained_word & c_index)
{
  chained_word l_file=c_file,l_index=c_index;

  // Boucle de lecture du file
  while(l_file!=NULL)
    {
      // Boucle de lecture de lindex
      while(l_index!=NULL)
	{
	  // Comparaison
	  if(l_index->word==l_file->word)
	    {
	      l_index->cpt+=1;
	      cout << "Mot trouve " << l_index->word << " a la ligne "<< l_file->cpt << endl;
	      l_index=NULL;
	    }
	  else
	    l_index=l_index->next;
	}
      l_index=c_index;
      l_file=l_file->next;
    }
}

void modif_cara( string & sentence )
{
  int cpt = 0 ;

  while( sentence[cpt] != '\n' && sentence[cpt]!='\0' && sentence[cpt] != EOF )
    { 
      if ( 'A' <= sentence[cpt] && sentence[cpt] <= 'Z' )  
	{ // toutes les majuscules trouvées seront modifiées en minuscule
	  int tmp_char = (int)(sentence[cpt]) ;
	  tmp_char += 32 ;
	  sentence[cpt] = (char)(tmp_char) ;
	}
      else // ne rien faire si lettre minuscule
	if ( 'a' <= sentence[cpt] && sentence[cpt] <= 'z' )
	  {}
	else
	  if(sentence[cpt] == '-' || sentence[cpt] == '\'')
	    transforme(sentence,cpt);
	  else
	    { // si caractere autre, changer par un espace
	      sentence[cpt] = ' ' ;
	    }
      cpt ++ ;
    }
}

void menu()
{
  string name_file("");
  chained_word c_file;
  chained_index c_index;
  int choix(-1);

  created_chained_word(c_file);
  created_chained_index(c_index);

  // Donner un nom de fichier pour remplir lindex
  test_open_file(name_file,1);

  // Lecture de name_file et stockage ds c_file
  read_file(name_file,c_file);
  print_chained(c_file);

  // Initialisation du fichier index
  initialisation_index(c_index);

  while(choix < 1 && 2 > choix)
    {
      cout << "Que voulez vous choisir ?" << endl;
      cout << "-> 1 pour arbre" << endl;
      cout << "-> 2 pour une table de hash" << endl;
      cin >> choix;
    }

  if(choix == 1)
    {
      tree t;
      create_tree(t);

      initialise_tree(t,c_index);

      add_ligne_tree(t,c_file);

      affiche_tree(t);

      delete_all_tree(t);

      if(t!=NULL)
	{
	  delete_all_index(t->item->c_i);
	  delete t->item;
	  delete t;
	}
    }
  else
    if(choix == 2)
      {
	chained_index hash_tab[TAILLE_HASH];

	create_hash(hash_tab);

	initialisation_hash(hash_tab,c_index);

	add_ligne_hash(hash_tab,c_file);

	affiche_hash(hash_tab);

	delete_all_hash(hash_tab);
      }
}
